home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_11_02
/
1102075a
< prev
next >
Wrap
Text File
|
1992-12-12
|
6KB
|
201 lines
/************************************************
*
* peak_threshold_segmentation(...
*
* This function segments an image using
* thresholding. It uses the histogram peaks
* to find the hi and low values of the
* threshold.
*
* If the segment parameter is 0, you only
* threshold the array - you do not segment.
*
*************************************************/
peak_threshold_segmentation(in_name, out_name,
the_image, out_image,
il, ie, ll, le,
value, segment)
char in_name[], out_name[];
int il, ie, ll, le, segment;
short the_image[ROWS][COLS],
out_image[ROWS][COLS], value;
{
int length, peak1, peak2, width;
short hi, low;
struct tiff_header_struct image_header;
unsigned long histogram[GRAY_LEVELS+1];
if(does_not_exist(out_name)){
printf("\n\nPTS> output file does not exist %s",
out_name);
read_tiff_header(in_name, &image_header);
round_off_image_size(&image_header,
&length, &width);
image_header.image_length = length*ROWS;
image_header.image_width = width*COLS;
create_allocate_tiff_file(out_name, &image_header,
out_image);
} /* ends if does_not_exist */
read_tiff_image(in_name, the_image, il, ie, ll, le);
zero_histogram(histogram);
calculate_histogram(the_image, histogram);
smooth_histogram(histogram);
find_peaks(histogram, &peak1, &peak2);
peaks_high_low(histogram, peak1, peak2,
&hi, &low);
threshold_image_array(the_image, out_image,
hi, low, value);
if(segment == 1)
grow(out_image, value);
write_array_into_tiff_image(out_name, out_image,
il, ie, ll, le);
} /* ends peak_threshold_segmentation */
/********************************************
*
* find_peaks(...
*
* This function looks through the histogram
* array and finds the two highest peaks.
* The peaks must be separated, cannot be
* next to each other, by a spacing defined
* in cips.h.
*
* The peaks array holds the peak value
* in the first place and its location in
* the second place.
*
*********************************************/
find_peaks(histogram, peak1, peak2)
unsigned long histogram[];
int *peak1, *peak2;
{
int distance[PEAKS], peaks[PEAKS][2];
int i, j=0, max=0, max_place=0;
for(i=0; i<PEAKS; i++){
distance[i] = 0;
peaks[i][0] = -1;
peaks[i][1] = -1;
}
for(i=0; i<=GRAY_LEVELS; i++){
max = histogram[i];
max_place = i;
insert_into_peaks(peaks, max, max_place);
} /* ends loop over i */
for(i=1; i<PEAKS; i++){
distance[i] = peaks[0][1] - peaks[i][1];
if(distance[i] < 0)
distance[i] = distance[i]*(-1);
}
*peak1 = peaks[0][1];
for(i=PEAKS-1; i>0; i--)
if(distance[i] > PEAK_SPACE) *peak2 = peaks[i][1];
} /* ends find_peaks */
/********************************************
*
* insert_into_peaks(...
*
* This function takes a value and its
* place in the histogram and inserts them
* into a peaks array. This helps us rank
* the the peaks in the histogram.
*
* The objective is to build a list of
* histogram peaks and thier locations.
*
* The peaks array holds the peak value
* in the first place and its location in
* the second place.
*
*********************************************/
insert_into_peaks(peaks, max, max_place)
int max, max_place, peaks[PEAKS][2];
{
int i, j;
/* first case */
if(max > peaks[0][0]){
for(i=PEAKS-1; i>0; i--){
peaks[i][0] = peaks[i-1][0];
peaks[i][1] = peaks[i-1][1];
}
peaks[0][0] = max;
peaks[0][1] = max_place;
} /* ends if */
/* middle cases */
for(j=0; j<PEAKS-3; j++){
if(max < peaks[j][0] && max > peaks[j+1][0]){
for(i=PEAKS-1; i>j+1; i--){
peaks[i][0] = peaks[i-1][0];
peaks[i][1] = peaks[i-1][1];
}
peaks[j+1][0] = max;
peaks[j+1][1] = max_place;
} /* ends if */
} /* ends loop over j */
/* last case */
if(max < peaks[PEAKS-2][0] && max > peaks[PEAKS-1][0]){
peaks[PEAKS-1][0] = max;
peaks[PEAKS-1][1] = max_place;
} /* ends if */
} /* ends insert_into_peaks */
/********************************************
*
* peaks_high_low(...
*
* This function uses the histogram array
* and the peaks to find the best high and
* low threshold values for the threshold
* function. You want the hi and low values
* so that you will threshold the image around
* the smaller of the two "humps" in the
* histogram. This is because the smaller
* hump represents the objects while the
* larger hump represents the background.
*
*********************************************/
peaks_high_low(histogram, peak1, peak2, hi, low)
int peak1, peak2;
short *hi, *low;
unsigned long histogram[];
{
int i, mid_point;
unsigned long sum1 = 0, sum2 = 0;
if(peak1 > peak2)
mid_point = ((peak1 - peak2)/2) + peak2;
if(peak1 < peak2)
mid_point = ((peak2 - peak1)/2) + peak1;
for(i=0; i<mid_point; i++)
sum1 = sum1 + histogram[i];
for(i=mid_point; i<=GRAY_LEVELS; i++)
sum2 = sum2 + histogram[i];
if(sum1 >= sum2){
*low = mid_point;
*hi = GRAY_LEVELS;
}
else{
*low = 0;
*hi = mid_point;
}
} /* ends peaks_high_low */